#pragma once
/** \file
* Defines the allocator interface as used by the KDTree class.
*
* \author Martin F. Krafft <libkdtree@pobox.madduck.net>
*/

#ifndef INCLUDE_KDTREE_ALLOCATOR_HPP
#define INCLUDE_KDTREE_ALLOCATOR_HPP

#include <cstddef>

#include "node.hpp"

namespace KDTree
{

	template <typename _Tp, typename _Alloc>
	class _Alloc_base
	{
	public:
		typedef _Node<_Tp> _Node_;
		typedef typename _Node_::_Base_ptr _Base_ptr;
		typedef _Alloc allocator_type;

		_Alloc_base(allocator_type const& __A)
			: _M_node_allocator(__A) {}

		allocator_type
			get_allocator() const
		{
			return _M_node_allocator;
		}


		class NoLeakAlloc
		{
			_Alloc_base * base;
			_Node_ * new_node;

		public:
			NoLeakAlloc(_Alloc_base * b) : base(b), new_node(base->_M_allocate_node()) {}

			_Node_ * get() { return new_node; }
			void disconnect() { new_node = NULL; }

			~NoLeakAlloc() { if (new_node) base->_M_deallocate_node(new_node); }
		};


	protected:
		allocator_type _M_node_allocator;

		_Node_*
			_M_allocate_node()
		{
			return _M_node_allocator.allocate(1);
		}

		void
			_M_deallocate_node(_Node_* const __P)
		{
			return _M_node_allocator.deallocate(__P, 1);
		}

		void
			_M_construct_node(_Node_* __p, _Tp const __V = _Tp(),
							  _Base_ptr const __PARENT = NULL,
							  _Base_ptr const __LEFT = NULL,
							  _Base_ptr const __RIGHT = NULL)
		{
			new (__p) _Node_(__V, __PARENT, __LEFT, __RIGHT);
		}

		void
			_M_destroy_node(_Node_* __p)
		{
			_M_node_allocator.destroy(__p);
		}
	};

} // namespace KDTree

#endif // include guard

  /* COPYRIGHT --
  *
  * This file is part of libkdtree++, a C++ template KD-Tree sorting container.
  * libkdtree++ is (c) 2004-2007 Martin F. Krafft <libkdtree@pobox.madduck.net>
  * and Sylvain Bougerel <sylvain.bougerel.devel@gmail.com> distributed under the
  * terms of the Artistic License 2.0. See the ./COPYING file in the source tree
  * root for more information.
  *
  * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
  * OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */